package com.shen.library_nettysocket.timer

import com.shen.library_nettysocket.interf.IMSClientInterface
import com.shen.library_nettysocket.protobuf.MessageProtobuf
import io.netty.util.internal.StringUtil
import java.util.concurrent.ConcurrentHashMap

/**
 * 「消息发送超时」管理器，用于管理消息定时器的「新增、移除」等
 *
 * [imsClient] ims客户端
 */
class MsgTimeoutTimerManager(private val imsClient: IMSClientInterface) {

    private val mMsgTimeoutMap: MutableMap<String, MsgTimeoutTimer> = ConcurrentHashMap()

    /**
     * 添加[msg]消息到「发送超时·管理器」
     */
    fun add(msg: MessageProtobuf.Msg?) {

        if (msg?.head == null) {
            return
        }

        var handshakeMsgType = -1
        var heartbeatMsgType = -1

        val clientReceivedReportMsgType: Int = imsClient.clientReceivedReportMsgType

        val handshakeMsg: MessageProtobuf.Msg? = imsClient.handshakeMsg
        if (handshakeMsg?.head != null) {
            handshakeMsgType = handshakeMsg.head.msgType
        }

        val heartbeatMsg: MessageProtobuf.Msg? = imsClient.heartbeatMsg
        if (heartbeatMsg?.head != null) {
            heartbeatMsgType = heartbeatMsg.head.msgType
        }

        val msgType: Int = msg.head.msgType
        // 「握手消息、心跳消息、客户端返回的状态报告消息」不用重发。
        if (msgType == handshakeMsgType || msgType == heartbeatMsgType || msgType == clientReceivedReportMsgType) {
            return
        }

        /* 这里相当于 -- 一个用户分配一个定时器 */
        val msgId: String = msg.head.msgId
        if (!mMsgTimeoutMap.containsKey(msgId)) {
            val timer = MsgTimeoutTimer(imsClient, msg)
            mMsgTimeoutMap[msgId] = timer
        }
        println("添加消息超发送超时管理器，message=" + msg + "\t当前管理器消息数：" + mMsgTimeoutMap.size)
    }

    /**
     * 从发送超时管理器中移除消息，并停止定时器
     *
     * @param msgId
     */
    fun remove(msgId: String) {
        if (StringUtil.isNullOrEmpty(msgId)) {
            return
        }
        var timer = mMsgTimeoutMap.remove(msgId)
        var msg: MessageProtobuf.Msg? = null
        if (timer != null) {
            msg = timer.getMsg()
            timer.cancel()
            timer = null
        }
        println("从发送消息管理器移除消息，message=$msg")
    }

    /**
     * 重连成功回调，重连并握手成功时，重发消息发送超时管理器中所有的消息
     */
    @Synchronized
    fun onResetConnected() {
        val it: Iterator<Map.Entry<String, MsgTimeoutTimer>> = mMsgTimeoutMap.entries.iterator()
        while (it.hasNext()) {
            it.next().value.sendMsg()
        }
    }

}